/**
 * Written By: Nicholas Hillier, Jan 16, 2009
 * Self explanitory scroller, that dispatches positioning events by percentage of scroll max and min
 */
package com.cbc.ourgame.slideshowmaker.components.ui
{
	import assets.scrollerassets.ScrollBarAsset;
	
	import caurina.transitions.Tweener;
	
	import com.cbc.ourgame.slideshowmaker.events.MeasurementEvent;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	
	[Event (name="scrollerPercent", type="com.cbc.ourgame.slideshowmaker.events.MeasurementEvent")]
	
	public class Scroller extends EventDispatcher
	{
		private const OBJECT_HEIGHT:Number = 289;
		private var _up:PressButton;
		private var _down:PressButton;
		private var _handle:DragButton;
		private var _track:Sprite;
		private var _view:ScrollBarAsset;
		
		private var _maxY:Number;
		private var _minY:Number;
		private var _totalScrollDistance:Number;
		private var _scrollOffset:Number;
		
		public function get view():ScrollBarAsset
		{
			return _view;
		}
		
		/**
		 * 
		 * @param view - A ScrollBarAsset created in the Flash IDE. 
		 * 
		 */
		public function Scroller(view:ScrollBarAsset)
		{
			_view = view;
			_up = new PressButton(view.up);
			_up.addCallback(scrollUp);
			_down = new PressButton(view.down);
			_down.addCallback(scrollDown);
			_handle = new DragButton(view.handle);
			_handle.addCallback(onDrag);
			_handle.mouseDownCall(onMouseDown);
			_track = view.track;
			
			_maxY = _track.y + _track.height - _handle.view.height;
			_minY = _track.y;
			_totalScrollDistance = _maxY - _minY;	
		}
		
		public function enable():void
		{
			_view.alpha = 1;
			_track.addEventListener(MouseEvent.CLICK, onTrackClick);
			_view.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
			_handle.enable();
			_up.enable();
			_down.enable();
		}
		
		public function disable():void
		{
			_view.alpha = 0.3;
			_track.removeEventListener(MouseEvent.CLICK, onTrackClick);
			_view.removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
			_handle.disable();
			_up.disable();
			_down.disable();
		}
		
		public function setHandle(height:Number):void
		{	
			var scale:Number = Math.max(0.1, Math.min(1, OBJECT_HEIGHT/height));
			_handle.view.scaleY = scale;
			
			_maxY = _track.y + _track.height - _handle.view.height;  
			_totalScrollDistance = _maxY - _minY;
			_handle.view.y = _minY;
			
			if(height < OBJECT_HEIGHT) disable();
			else enable();
		}
		
		public function scroll(value:Number):void
		{
			_handle.view.y += value;
			_handle.view.y = Math.max(_minY, Math.min(_maxY, _handle.view.y));
			dispatch();
		}
		
		private function scrollUp(e:Event):void
		{
			scroll(-5);
		}
		
		private function scrollDown(e:Event):void
		{
			scroll(5);
		}
		
		private function onDrag(e:MouseEvent):void
		{
			_handle.view.y = Math.max(_minY, Math.min(_maxY, view.mouseY- _scrollOffset));
			dispatch();
		}
		
		private function onMouseDown():void
		{
			_scrollOffset = view.mouseY - _handle.view.y;
		}
		
		private function onTrackClick(e:MouseEvent):void
		{
			var yPos:Number = Math.max(_minY, Math.min(_maxY, _track.mouseY));
			Tweener.addTween(_handle.view, {y:yPos, time:0.3, onUpdate:dispatch});
		}
		
		private function dispatch():void
		{
			dispatchEvent(new MeasurementEvent(MeasurementEvent.SCROLLER_PERCENT, (_handle.view.y - _minY)/_totalScrollDistance));	
		}
		
		private function onMouseWheel(e:MouseEvent):void
		{
			scroll(e.delta*-2);
		}

	}
}